<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>cmt.rig.swingtwist &#8212; cmt  documentation</title>
    <link rel="stylesheet" href="../../../_static/bootstrap-sphinx.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <script src="../../../_static/language_data.js"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name="apple-mobile-web-app-capable" content="yes">
<script type="text/javascript" src="../../../_static/js/jquery-1.11.0.min.js "></script>
<script type="text/javascript" src="../../../_static/js/jquery-fix.js "></script>
<script type="text/javascript" src="../../../_static/bootstrap-3.3.7/js/bootstrap.min.js "></script>
<script type="text/javascript" src="../../../_static/bootstrap-sphinx.js "></script>

  </head><body>

  <div id="navbar" class="navbar navbar-default navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="../../../index.html">
          cmt</a>
        <span class="navbar-text navbar-version pull-left"><b></b></span>
      </div>

        <div class="collapse navbar-collapse nav-collapse">
          <ul class="nav navbar-nav">
            
            
              <li class="dropdown globaltoc-container">
  <a role="button"
     id="dLabelGlobalToc"
     data-toggle="dropdown"
     data-target="#"
     href="../../../index.html">Site <b class="caret"></b></a>
  <ul class="dropdown-menu globaltoc"
      role="menu"
      aria-labelledby="dLabelGlobalToc"><ul>
<li class="toctree-l1"><a class="reference internal" href="../../../installation.html">Installation Instructions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rigging.html">Rigging Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../dge.html">Dependency Graph Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../customwidgets.html">Custom Widgets</a></li>
</ul>
</ul>
</li>
              
                <li class="dropdown">
  <a role="button"
     id="dLabelLocalToc"
     data-toggle="dropdown"
     data-target="#"
     href="#">Page <b class="caret"></b></a>
  <ul class="dropdown-menu localtoc"
      role="menu"
      aria-labelledby="dLabelLocalToc"></ul>
</li>
              
            
            
              
                
              
            
            
            
            
              <li class="hidden-sm"></li>
            
          </ul>

          
            
<form class="navbar-form navbar-right" action="../../../search.html" method="get">
 <div class="form-group">
  <input type="text" name="q" class="form-control" placeholder="Search" />
 </div>
  <input type="hidden" name="check_keywords" value="yes" />
  <input type="hidden" name="area" value="default" />
</form>
          
        </div>
    </div>
  </div>

<div class="container">
  <div class="row">
    <div class="body col-md-12 content" role="main">
      
  <h1>Source code for cmt.rig.swingtwist</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;Creates a node network to extract swing/twist rotation of a transform to drive</span>
<span class="sd">another transforms offsetParentMatrix.</span>

<span class="sd">The network calculates the local rotation swing and twist offset around the specified</span>
<span class="sd">twist axis relative to the local rest orientation.  This allows users to specify how</span>
<span class="sd">much swing and twist they want to propagate to another transform.  Uses include driving</span>
<span class="sd">an upper arm twist joint from the shoulder and driving forearm twist joints from the</span>
<span class="sd">wrist.</span>

<span class="sd">.. raw:: html</span>

<span class="sd">    &lt;div style=&quot;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&quot;&gt;</span>
<span class="sd">      &lt;iframe src=&quot;https://www.youtube.com/embed/12tyQc93Y7A&quot; style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&quot; allowfullscreen title=&quot;YouTube Video&quot;&gt;&lt;/iframe&gt;</span>
<span class="sd">    &lt;/div&gt;</span>


<span class="sd">Since the network uses quaternions, partial swing and twist values between 0.0 and 1.0</span>
<span class="sd">will see a flip when the driver transform rotates past 180 degrees.</span>

<span class="sd">The setup can either be made with several standard Maya nodes, or the compiled plug-in</span>
<span class="sd">can be used to create a single node. Setting cmt.settings.ENABLE_PLUGINS to False will</span>
<span class="sd">use vanilla Maya nodes. Otherwise, the compiled plug-in will be used.</span>

<span class="sd">Example Usage</span>
<span class="sd">=============</span>
<span class="sd">The twist decomposition network can be accessed in the cmt menu::</span>

<span class="sd">    CMT &gt; Rigging &gt; Connect Twist Joint</span>

<span class="sd">Twist child of shoulder::</span>

<span class="sd">    shoulder</span>
<span class="sd">      |- twist_joint1</span>
<span class="sd">      |- twist_joint2</span>
<span class="sd">      |- elbow</span>

<span class="sd">    create_swing_twist(shoulder, twist_joint1, twist_weight=-1.0, swing_weight=0.0)</span>
<span class="sd">    create_swing_twist(shoulder, twist_joint2, twist_weight=-0.5, swing_weight=0.0)</span>

<span class="sd">Twist forearm from wrist::</span>

<span class="sd">    elbow</span>
<span class="sd">      |- twist_joint1</span>
<span class="sd">      |- twist_joint2</span>
<span class="sd">      |- wrist</span>

<span class="sd">    create_swing_twist(wrist, twist_joint1, twist_weight=0.5, swing_weight=0.0)</span>
<span class="sd">    create_swing_twist(wrist, twist_joint2, twist_weight=1.0, swing_weight=0.0)</span>

<span class="sd">Use no plugins::</span>

<span class="sd">    import cmt.settings as settings</span>
<span class="sd">    settings.ENABLE_PLUGINS = False</span>
<span class="sd">    create_swing_twist(wrist, twist_joint1, twist_weight=0.5, swing_weight=0.0)</span>
<span class="sd">    create_swing_twist(wrist, twist_joint2, twist_weight=1.0, swing_weight=0.0)</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">absolute_import</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">division</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>

<span class="kn">import</span> <span class="nn">logging</span>

<span class="kn">import</span> <span class="nn">maya.cmds</span> <span class="k">as</span> <span class="nn">cmds</span>
<span class="kn">import</span> <span class="nn">maya.mel</span> <span class="k">as</span> <span class="nn">mel</span>
<span class="kn">import</span> <span class="nn">maya.api.OpenMaya</span> <span class="k">as</span> <span class="nn">OpenMaya</span>

<span class="kn">from</span> <span class="nn">cmt.ui.optionbox</span> <span class="kn">import</span> <span class="n">OptionBox</span>
<span class="kn">from</span> <span class="nn">cmt.settings</span> <span class="kn">import</span> <span class="n">DOCUMENTATION_ROOT</span>
<span class="kn">import</span> <span class="nn">cmt.settings</span> <span class="k">as</span> <span class="nn">settings</span>
<span class="kn">from</span> <span class="nn">cmt.dge</span> <span class="kn">import</span> <span class="n">dge</span>
<span class="kn">import</span> <span class="nn">cmt.shortcuts</span> <span class="k">as</span> <span class="nn">shortcuts</span>
<span class="kn">import</span> <span class="nn">math</span>

<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>

<span class="c1"># User defined attribute names used in the network</span>
<span class="n">TWIST_WEIGHT</span> <span class="o">=</span> <span class="s2">&quot;twist&quot;</span>
<span class="n">SWING_WEIGHT</span> <span class="o">=</span> <span class="s2">&quot;swing&quot;</span>
<span class="n">TWIST_OUTPUT</span> <span class="o">=</span> <span class="s2">&quot;twistOutput&quot;</span>
<span class="n">INV_TWIST_OUTPUT</span> <span class="o">=</span> <span class="s2">&quot;invertedTwistOutput&quot;</span>
<span class="n">SWING_OUTPUT</span> <span class="o">=</span> <span class="s2">&quot;swingOutput&quot;</span>
<span class="n">INV_SWING_OUTPUT</span> <span class="o">=</span> <span class="s2">&quot;invertedSwingOutput&quot;</span>

<span class="n">HELP_URL</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">/rig/swingtwist.html&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">DOCUMENTATION_ROOT</span><span class="p">)</span>


<div class="viewcode-block" id="create_swing_twist"><a class="viewcode-back" href="../../../rig/swingtwist.html#cmt.rig.swingtwist.create_swing_twist">[docs]</a><span class="k">def</span> <span class="nf">create_swing_twist</span><span class="p">(</span>
    <span class="n">driver</span><span class="p">,</span> <span class="n">driven</span><span class="p">,</span> <span class="n">twist_weight</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">swing_weight</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">twist_axis</span><span class="o">=</span><span class="mi">0</span>
<span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Create a node network to drive a transforms offsetParentMatrix from the</span>
<span class="sd">    decomposed swing/twist of another transform.</span>

<span class="sd">    Setting cmt.settings.ENABLE_PLUGINS to False will use vanilla Maya nodes. Otherwise,</span>
<span class="sd">    the compiled plug-in will be used.</span>

<span class="sd">    :param driver: Driver transform</span>
<span class="sd">    :param driven: Driven transform</span>
<span class="sd">    :param twist_weight: -1 to 1 twist scalar</span>
<span class="sd">    :param swing_weight: -1 to 1 swing scalar</span>
<span class="sd">    :param twist_axis: Local twist axis on driver (0: X, 1: Y, 2: Z)</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">ENABLE_PLUGINS</span><span class="p">:</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">loadPlugin</span><span class="p">(</span><span class="s2">&quot;cmt&quot;</span><span class="p">,</span> <span class="n">qt</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">swingTwist</span><span class="p">(</span>
            <span class="n">driver</span><span class="p">,</span> <span class="n">driven</span><span class="p">,</span> <span class="n">twist</span><span class="o">=</span><span class="n">twist_weight</span><span class="p">,</span> <span class="n">swing</span><span class="o">=</span><span class="n">swing_weight</span><span class="p">,</span> <span class="n">twistAxis</span><span class="o">=</span><span class="n">twist_axis</span>
        <span class="p">)</span>
        <span class="k">return</span>
    <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">[</span><span class="n">TWIST_OUTPUT</span><span class="p">,</span> <span class="n">INV_TWIST_OUTPUT</span><span class="p">,</span> <span class="n">SWING_OUTPUT</span><span class="p">,</span> <span class="n">INV_SWING_OUTPUT</span><span class="p">]:</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">cmds</span><span class="o">.</span><span class="n">objExists</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">attr</span><span class="p">)):</span>
            <span class="n">cmds</span><span class="o">.</span><span class="n">addAttr</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">ln</span><span class="o">=</span><span class="n">attr</span><span class="p">,</span> <span class="n">at</span><span class="o">=</span><span class="s2">&quot;message&quot;</span><span class="p">)</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">_twist_network_exists</span><span class="p">(</span><span class="n">driver</span><span class="p">):</span>
        <span class="n">_create_twist_decomposition_network</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">twist_axis</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">[</span><span class="n">TWIST_WEIGHT</span><span class="p">,</span> <span class="n">SWING_WEIGHT</span><span class="p">]:</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">cmds</span><span class="o">.</span><span class="n">objExists</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attr</span><span class="p">)):</span>
            <span class="n">cmds</span><span class="o">.</span><span class="n">addAttr</span><span class="p">(</span>
                <span class="n">driven</span><span class="p">,</span>
                <span class="n">ln</span><span class="o">=</span><span class="n">attr</span><span class="p">,</span>
                <span class="n">keyable</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
                <span class="n">minValue</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                <span class="n">maxValue</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                <span class="n">defaultValue</span><span class="o">=</span><span class="n">math</span><span class="o">.</span><span class="n">fabs</span><span class="p">(</span><span class="n">twist_weight</span><span class="p">),</span>
            <span class="p">)</span>

    <span class="n">twist</span><span class="p">,</span> <span class="n">inv_twist</span><span class="p">,</span> <span class="n">swing</span><span class="p">,</span> <span class="n">inv_swing</span> <span class="o">=</span> <span class="n">_get_swing_twist_attributes</span><span class="p">(</span><span class="n">driver</span><span class="p">)</span>

    <span class="n">twist_slerp</span> <span class="o">=</span> <span class="n">_create_slerp</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">twist_weight</span><span class="p">,</span> <span class="n">twist</span><span class="p">,</span> <span class="n">inv_twist</span><span class="p">,</span> <span class="n">TWIST_WEIGHT</span><span class="p">)</span>
    <span class="n">swing_slerp</span> <span class="o">=</span> <span class="n">_create_slerp</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">swing_weight</span><span class="p">,</span> <span class="n">swing</span><span class="p">,</span> <span class="n">inv_swing</span><span class="p">,</span> <span class="n">SWING_WEIGHT</span><span class="p">)</span>

    <span class="n">rotation</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;quatProd&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_rotation&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">twist_slerp</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.input1Quat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation</span><span class="p">)</span>
    <span class="p">)</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">swing_slerp</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.input2Quat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation</span><span class="p">)</span>
    <span class="p">)</span>

    <span class="n">rotation_matrix</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span>
        <span class="s2">&quot;composeMatrix&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_rotation_matrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">)</span>
    <span class="p">)</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.useEulerRotation&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation_matrix</span><span class="p">),</span> <span class="mi">0</span><span class="p">)</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation_matrix</span><span class="p">)</span>
    <span class="p">)</span>

    <span class="n">mult</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;multMatrix&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_offset_parent_matrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation_matrix</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">)</span>
    <span class="p">)</span>

    <span class="n">pinv</span> <span class="o">=</span> <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.parentInverseMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">)))</span>
    <span class="n">m</span> <span class="o">=</span> <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.worldMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">)))</span>
    <span class="n">local_rest_matrix</span> <span class="o">=</span> <span class="n">m</span> <span class="o">*</span> <span class="n">pinv</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[1]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">),</span> <span class="nb">list</span><span class="p">(</span><span class="n">local_rest_matrix</span><span class="p">),</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;matrix&quot;</span><span class="p">)</span>

    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixSum&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.offsetParentMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">)</span>
    <span class="p">)</span>

    <span class="c1"># Zero out local xforms to prevent double xform</span>
    <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;</span><span class="si">{}{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;t&quot;</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">,</span> <span class="s2">&quot;jo&quot;</span><span class="p">]</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="s2">&quot;xyz&quot;</span><span class="p">]:</span>
        <span class="n">is_locked</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attr</span><span class="p">),</span> <span class="n">lock</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">is_locked</span><span class="p">:</span>
            <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attr</span><span class="p">),</span> <span class="n">lock</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attr</span><span class="p">),</span> <span class="mf">0.0</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">is_locked</span><span class="p">:</span>
            <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attr</span><span class="p">),</span> <span class="n">lock</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
        <span class="s2">&quot;Created swing twist network to drive </span><span class="si">{}</span><span class="s2"> from </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">driver</span><span class="p">)</span>
    <span class="p">)</span></div>


<span class="k">def</span> <span class="nf">_twist_network_exists</span><span class="p">(</span><span class="n">driver</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Test whether the twist decomposition network already exists on driver.</span>

<span class="sd">    :param driver: Driver transform</span>
<span class="sd">    :return: True or False</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">has_twist_attribute</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">objExists</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">TWIST_OUTPUT</span><span class="p">))</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">has_twist_attribute</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="n">twist_node</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">listConnections</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">TWIST_OUTPUT</span><span class="p">),</span> <span class="n">d</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
    <span class="k">return</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">twist_node</span> <span class="k">else</span> <span class="kc">False</span>


<span class="k">def</span> <span class="nf">_create_twist_decomposition_network</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">twist_axis</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Create the twist decomposition network for driver.</span>

<span class="sd">    :param driver: Driver transform</span>
<span class="sd">    :param twist_axis: Local twist axis on driver</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># Connect message attributes to the decomposed twist nodes so we can reuse them</span>
    <span class="c1"># if the network is driving multiple nodes</span>

    <span class="n">mult</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;multMatrix&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_local_matrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">))</span>
    <span class="n">parent_inverse</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.parentInverseMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">)</span>
    <span class="n">world_matrix</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.worldMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">)</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="n">world_matrix</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="n">parent_inverse</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[1]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">))</span>
    <span class="n">pinv</span> <span class="o">=</span> <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="n">parent_inverse</span><span class="p">))</span>
    <span class="n">m</span> <span class="o">=</span> <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="n">world_matrix</span><span class="p">))</span>
    <span class="n">inv_local_rest_matrix</span> <span class="o">=</span> <span class="p">(</span><span class="n">m</span> <span class="o">*</span> <span class="n">pinv</span><span class="p">)</span><span class="o">.</span><span class="n">inverse</span><span class="p">()</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[2]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">),</span> <span class="nb">list</span><span class="p">(</span><span class="n">inv_local_rest_matrix</span><span class="p">),</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;matrix&quot;</span>
    <span class="p">)</span>

    <span class="n">rotation</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;decomposeMatrix&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_rotation&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixSum&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation</span><span class="p">))</span>

    <span class="n">twist</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;quatNormalize&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_twist&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat.outputQuatW&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation</span><span class="p">),</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputQuat.inputQuatW&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">twist</span><span class="p">),</span>
    <span class="p">)</span>
    <span class="n">axis</span> <span class="o">=</span> <span class="s2">&quot;XYZ&quot;</span><span class="p">[</span><span class="n">twist_axis</span><span class="p">]</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat.outputQuat</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation</span><span class="p">,</span> <span class="n">axis</span><span class="p">),</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputQuat.inputQuat</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">twist</span><span class="p">,</span> <span class="n">axis</span><span class="p">),</span>
    <span class="p">)</span>

    <span class="c1"># swing = twist.inverse() * rotation</span>
    <span class="n">inv_twist</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;quatInvert&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_inverse_twist&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">twist</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">inv_twist</span><span class="p">))</span>
    <span class="n">swing</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;quatProd&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_swing&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">inv_twist</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.input1Quat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">swing</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rotation</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.input2Quat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">swing</span><span class="p">))</span>

    <span class="n">inv_swing</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;quatInvert&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_inverse_swing&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">swing</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">inv_swing</span><span class="p">))</span>

    <span class="c1"># Connect the nodes to the driver so we can find and reuse them for multiple setups</span>
    <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">[</span>
        <span class="p">(</span><span class="n">twist</span><span class="p">,</span> <span class="n">TWIST_OUTPUT</span><span class="p">),</span>
        <span class="p">(</span><span class="n">inv_twist</span><span class="p">,</span> <span class="n">INV_TWIST_OUTPUT</span><span class="p">),</span>
        <span class="p">(</span><span class="n">swing</span><span class="p">,</span> <span class="n">SWING_OUTPUT</span><span class="p">),</span>
        <span class="p">(</span><span class="n">inv_swing</span><span class="p">,</span> <span class="n">INV_SWING_OUTPUT</span><span class="p">),</span>
    <span class="p">]:</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.message&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">attr</span><span class="p">))</span>


<span class="k">def</span> <span class="nf">_get_swing_twist_attributes</span><span class="p">(</span><span class="n">driver</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Get the quaternion output attribute of the twist decomposition network.</span>

<span class="sd">    :param driver: Driver transform</span>
<span class="sd">    :param invert: True to get the inverted twist attribute</span>
<span class="sd">    :param twist_axis: Local twist axis of driver</span>
<span class="sd">    :return: The quaternion output attribute</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">nodes</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">[</span><span class="n">TWIST_OUTPUT</span><span class="p">,</span> <span class="n">INV_TWIST_OUTPUT</span><span class="p">,</span> <span class="n">SWING_OUTPUT</span><span class="p">,</span> <span class="n">INV_SWING_OUTPUT</span><span class="p">]:</span>
        <span class="n">node</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">listConnections</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">attr</span><span class="p">),</span> <span class="n">d</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">node</span><span class="p">:</span>
            <span class="c1"># The network isn&#39;t connected so create it</span>
            <span class="n">_create_twist_decomposition_network</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">twist_axis</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">_get_swing_twist_attributes</span><span class="p">(</span><span class="n">driver</span><span class="p">)</span>
        <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>

    <span class="k">return</span> <span class="p">[</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputQuat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodes</span><span class="p">]</span>


<span class="k">def</span> <span class="nf">_create_slerp</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">weight</span><span class="p">,</span> <span class="n">rotation</span><span class="p">,</span> <span class="n">inv_rotation</span><span class="p">,</span> <span class="n">attribute</span><span class="p">):</span>
    <span class="n">slerp</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;quatSlerp&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_</span><span class="si">{}</span><span class="s2">_slerp&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attribute</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attribute</span><span class="p">),</span> <span class="n">math</span><span class="o">.</span><span class="n">fabs</span><span class="p">(</span><span class="n">weight</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driven</span><span class="p">,</span> <span class="n">attribute</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputT&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">slerp</span><span class="p">))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.input1QuatW&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">slerp</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">weight</span> <span class="o">&gt;=</span> <span class="mf">0.0</span><span class="p">:</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="n">rotation</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.input2Quat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">slerp</span><span class="p">))</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="n">inv_rotation</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.input2Quat&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">slerp</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">slerp</span>


<span class="k">def</span> <span class="nf">create_from_menu</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">sel</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">ls</span><span class="p">(</span><span class="n">sl</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sel</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Select driver transform then driven transform.&quot;</span><span class="p">)</span>
    <span class="n">driver</span><span class="p">,</span> <span class="n">driven</span> <span class="o">=</span> <span class="n">sel</span>
    <span class="n">kwargs</span> <span class="o">=</span> <span class="n">Options</span><span class="o">.</span><span class="n">get_kwargs</span><span class="p">()</span>
    <span class="n">create_swing_twist</span><span class="p">(</span><span class="n">driver</span><span class="p">,</span> <span class="n">driven</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">display_menu_options</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">options</span> <span class="o">=</span> <span class="n">Options</span><span class="p">(</span><span class="s2">&quot;Swing Twist Options&quot;</span><span class="p">,</span> <span class="n">HELP_URL</span><span class="p">)</span>
    <span class="n">options</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>


<span class="k">class</span> <span class="nc">Options</span><span class="p">(</span><span class="n">OptionBox</span><span class="p">):</span>
    <span class="n">SWING_WEIGHT_WIDGET</span> <span class="o">=</span> <span class="s2">&quot;cmt_swing_weight&quot;</span>
    <span class="n">TWIST_WEIGHT_WIDGET</span> <span class="o">=</span> <span class="s2">&quot;cmt_twist_weight&quot;</span>
    <span class="n">TWIST_AXIS_WIDGET</span> <span class="o">=</span> <span class="s2">&quot;cmt_twist_axis&quot;</span>

    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">get_kwargs</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Gets the function arguments either from the option box widgets or the saved</span>
<span class="sd">        option vars.  If the widgets exist, their values will be saved to the option</span>
<span class="sd">        vars.</span>

<span class="sd">        :return: A dictionary of the arguments to the create_twist_decomposition</span>
<span class="sd">        function.&quot;&quot;&quot;</span>
        <span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">if</span> <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">exists</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
            <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;twist_weight&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span>
                <span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">q</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="kc">True</span>
            <span class="p">)</span>
            <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">fv</span><span class="o">=</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;twist_weight&quot;</span><span class="p">]))</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;twist_weight&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">q</span><span class="o">=</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">SWING_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">exists</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
            <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;swing_weight&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span>
                <span class="n">Options</span><span class="o">.</span><span class="n">SWING_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">q</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="kc">True</span>
            <span class="p">)</span>
            <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">fv</span><span class="o">=</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">SWING_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;swing_weight&quot;</span><span class="p">]))</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;twist_weight&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">q</span><span class="o">=</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionMenuGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">,</span> <span class="n">exists</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
            <span class="n">value</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionMenuGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">,</span> <span class="n">q</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">sl</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
            <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;twist_axis&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> <span class="o">-</span> <span class="mi">1</span>
            <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">iv</span><span class="o">=</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;twist_axis&quot;</span><span class="p">]))</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;twist_axis&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">q</span><span class="o">=</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">kwargs</span>

    <span class="k">def</span> <span class="nf">create_ui</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">columnLayout</span><span class="p">(</span><span class="n">adj</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">widget</span> <span class="ow">in</span> <span class="p">[</span>
            <span class="n">Options</span><span class="o">.</span><span class="n">SWING_WEIGHT_WIDGET</span><span class="p">,</span>
            <span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">,</span>
            <span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">,</span>
        <span class="p">]:</span>
            <span class="c1"># Delete the widgets so we don&#39;t create multiple controls with the same name</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">cmds</span><span class="o">.</span><span class="n">deleteUI</span><span class="p">(</span><span class="n">widget</span><span class="p">,</span> <span class="n">control</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
            <span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
                <span class="k">pass</span>

        <span class="n">swing_weight</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">q</span><span class="o">=</span><span class="n">Options</span><span class="o">.</span><span class="n">SWING_WEIGHT_WIDGET</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span>
            <span class="n">Options</span><span class="o">.</span><span class="n">SWING_WEIGHT_WIDGET</span><span class="p">,</span>
            <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Swing weight&quot;</span><span class="p">,</span>
            <span class="n">field</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
            <span class="n">minValue</span><span class="o">=-</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">maxValue</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">fieldMinValue</span><span class="o">=-</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">fieldMaxValue</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">value</span><span class="o">=</span><span class="n">swing_weight</span><span class="p">,</span>
            <span class="n">step</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>
            <span class="n">precision</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
        <span class="p">)</span>

        <span class="n">twist_weight</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">q</span><span class="o">=</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span>
            <span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">,</span>
            <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Twist weight&quot;</span><span class="p">,</span>
            <span class="n">field</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
            <span class="n">minValue</span><span class="o">=-</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">maxValue</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">fieldMinValue</span><span class="o">=-</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">fieldMaxValue</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span>
            <span class="n">value</span><span class="o">=</span><span class="n">twist_weight</span><span class="p">,</span>
            <span class="n">step</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>
            <span class="n">precision</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
        <span class="p">)</span>

        <span class="n">twist_axis</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">optionVar</span><span class="p">(</span><span class="n">q</span><span class="o">=</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">)</span>
        <span class="n">twist_axis</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">twist_axis</span> <span class="k">else</span> <span class="n">twist_axis</span> <span class="o">+</span> <span class="mi">1</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">optionMenuGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">,</span> <span class="n">l</span><span class="o">=</span><span class="s2">&quot;Twist Axis&quot;</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">menuItem</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;X&quot;</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">menuItem</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Y&quot;</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">menuItem</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Z&quot;</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">optionMenuGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">,</span> <span class="n">e</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">sl</span><span class="o">=</span><span class="n">twist_axis</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">on_apply</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">create_from_menu</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">on_reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">SWING_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">e</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">floatSliderGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_WEIGHT_WIDGET</span><span class="p">,</span> <span class="n">e</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">optionMenuGrp</span><span class="p">(</span><span class="n">Options</span><span class="o">.</span><span class="n">TWIST_AXIS_WIDGET</span><span class="p">,</span> <span class="n">e</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">sl</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">on_save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">Options</span><span class="o">.</span><span class="n">get_kwargs</span><span class="p">()</span>
</pre></div>

    </div>
      
  </div>
</div>
<footer class="footer">
  <div class="container">
    <p class="pull-right">
      <a href="#">Back to top</a>
      
    </p>
    <p>
        &copy; Copyright 2018, Chad Vernon.<br/>
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.1.2.<br/>
    </p>
  </div>
</footer>
  </body>
</html>